; Music of Player Duffy Music Pro (199x) (Duffy & Benjy & NDC Team)
; Ripped by Megachur the 19/08/2008

;	write "PLADMP01.BIN"
;	write "PLADMP02.BIN"
;	write "PLADMP03.BIN"
;	write "PLADMP04.BIN"
;	write "PLADMP05.BIN"
;	write "PLADMP06.BIN"
;	write "PLADMP07.BIN"
;	write "PLADMP08.BIN"
;	write "PLADMP09.BIN"
;;;;;	write "PLADMP10.BIN" need NDC player !!!
;	write "PLADMP11.BIN"
;	write "PLADMP12.BIN"
;	write "PLADMP13.BIN"
;	write "PLADMP14.BIN"

music_date_rip	equ &1388
music_adr	equ &8900
first_theme	equ 0
last_theme	equ 0	; 0 -> 0

	read "music_header_v1_0.asm"
;
;
;;        ***************************************
;;        *   Player pour MUSIC PRO par Benjy   *
;;        *   Appel :                           *
;;        *    Initialisation : CALL init       *
;;        *     CE : HL : Adr de la musique     *
;;        *    Audition : CALL play             *
;;        *     Tous les 1/50eme de seconde     *
;;        *    Bruitages : CALL bruitage        *
;;        *     CE : B : No du son              *
;;        *          A : Voie a interrompre     *
;;        ***************************************
;
;
	JP	init_music	; HL - Adr de la musique
	JP	play_music	; tous les 1/50eme de seconde
	JP	bruitage 	; 	joue un son
;
adrmus		DW	0	;adr de la musique (a ajouter)
;
voie1		DB	15	;volume maximum
v1volume	DB	0	;contient en permanence le volume
v1son		DB	0	;contient le no du son courant
v1adrson	DW	0	;adresse du son courant
v1freq		DW	0	;contient la frequence courante
v1bruit		DB	0	;bruit courant
v1adrseq	DW	0	;adresse du premier no de sequence
v1seq		DW	0	;pointeur sur le no de seq courant
v1adrnot	DW	0	;pointeur sur la note courante
v1nbrnot	DB	0	;nombre de notes
v1durnot	DB	0	;duree de la note courante
v1adrenv	DW	0	;adr dans ENV
v1durenv	DB	0	;duree portion d'ENV
v1pntenv	DB	0	;pente d'ENV
v1adrent	DW	0	;adr dans ENT
v1durent	DB	0	;duree portion ENT
v1pntent	DB	0	;pente d'ENT
v1rgfreq	DB	0	;registre controlant la freq
v1rgvolu	DB	8	;registre controlant l'amplitude
v1penv		DB	0	;no de portion d'ENV
v1pent		DB	0	;no de portion d'ENT
v1cinvev	DB	1	;inverse de pntenv (constant)
v1invev		DB	1	;inverse de pntenv (compteur)
v1cinvet	DB	1	;inverse de pntent (constant)
v1invet		DB	1	;inverse de pntent (compteur)
v1status	DB	0	; 0-normal ; 1-soupir ; 2-DO 0
;
voie2		DB	15	;volume maximum
v2volume	DB	0	;contient en permanence le volume
v2son		DB	0	;contient le no du son courant
v2adrson	DW	0	;adresse du son courant
v2freq		DW	0	;contient la frequence courante
v2bruit		DB	0	;bruit courant
v2adrseq	DW	0	;adresse du premier no de sequence
v2seq		DW	0	;pointeur sur le no de seq courant
v2adrnot	DW	0	;pointeur sur la note courante
v2nbrnot	DB	0	;nombre de notes
v2durnot	DB	0	;duree de la note courante
v2adrenv	DW	0	;adr dans ENV
v2durenv	DB	0	;duree portion d'ENV
v2pntenv	DB	0	;pente d'ENV
v2adrent	DW	0	;adr dans ENT
v2durent	DB	0	;duree portion ENT
v2pntent	DB	0	;pente d'ENT
v2rgfreq	DB	2	;registre controlant la freq
v2rgvolu	DB	9	;registre controlant l'amplitude
v2penv		DB	0	;no de portion d'ENV
v2pent		DB	0	;no de portion d'ENT
v2cinvev	DB	1	;inverse de pntenv (constant)
v2invev		DB	1	;inverse de pntenv (compteur)
v2cinvet	DB	1	;inverse de pntent (constant)
v2invet		DB	1	;inverse de pntent (compteur)
v2status	DB	0	; 0-normal ; 1-soupir ; 2-DO 0
;
voie3		DB	15	;volume maximum
v3volume	DB	0	;contient en permanence le volume
v3son		DB	0	;contient le no du son courant
v3adrson	DW	0	;adresse du son courant
v3freq		DW	0	;contient la frequence courante
v3bruit		DB	0	;bruit courant
v3adrseq	DW	0	;adresse du premier no de sequence
v3seq		DW	0	;pointeur sur le no de seq courant
v3adrnot	DW	0	;pointeur sur la note courante
v3nbrnot	DB	0	;nombre de notes
v3durnot	DB	0	;duree de la note courante
v3adrenv	DW	0	;adr dans ENV
v3durenv	DB	0	;duree portion d'ENV
v3pntenv	DB	0	;pente d'ENV
v3adrent	DW	0	;adr dans ENT
v3durent	DB	0	;duree portion ENT
v3pntent	DB	0	;pente d'ENT
v3rgfreq	DB	4	;registre controlant la freq
v3rgvolu	DB	10	;registre controlant l'amplitude
v3penv		DB	0	;no de portion d'ENV
v3pent		DB	0	;no de portion d'ENT
v3cinvev	DB	1	;inverse de pntenv (constant)
v3invev		DB	1	;inverse de pntenv (compteur)
v3cinvet	DB	1	;inverse de pntent (constant)
v3invet		DB	1	;inverse de pntent (compteur)
v3status	DB	0	; 0-normal ; 1-soupir ; 2-DO 0
;                               ; 3-son en attente ; 4-son joue
;                               ; 5-son termine
;
bruitage
	LD	ix,voie1
	CP	1
	JP	z,bruitsui
	LD	ix,voie2
	CP	2
	JP	z,bruitsui
	LD	ix,voie3
bruitsui
	LD	(ix+32),3	;sample request
	LD	(ix+2),b
	RET	
;
.init_music
;
	ld hl,musicdata		; added by Megachur
	PUSH	hl
	POP	ix
	LD	(adrmus),hl
;
	LD	e,(ix+6)	; init adrseq sur premiere sequence
	LD	d,(ix+7)
	LD	(v1adrseq),de
	LD	(v1seq),de
;
	LD	e,(ix+8)
	LD	d,(ix+9)
	LD	(v2adrseq),de
	LD	(v2seq),de
;
	LD	e,(ix+10)
	LD	d,(ix+11)
	LD	(v3adrseq),de
	LD	(v3seq),de
;
	LD	a,15		; init volume maximum
	LD	(voie1),a
	LD	(voie2),a
	LD	(voie3),a
;
	XOR	a
	LD	(v1nbrnot),a	; plus de notes
	LD	(v1durnot),a	; derniere note finie
	LD	(v2nbrnot),a	; plus de notes
	LD	(v2durnot),a	; derniere note finie
	LD	(v3nbrnot),a	; plus de notes
	LD	(v3durnot),a	; derniere note finie
;
	LD	a,11	; init buzzer
	LD	c,1	; periode 1
	CALL	mc
	LD	a,12
	LD	c,0
	CALL	mc
	LD	a,13	; ENV hard no 8
	LD	c,8
	CALL	mc
;
	RET	
;
.play_music
;
	LD	ix,voie1
	CALL	playvoie
	LD	ix,voie2
	CALL	playvoie
	LD	ix,voie3
	CALL	playvoie
;
	LD	c,0	; controle du melange du bruit
	LD	a,(v1bruit)
	OR	a
	JP	nz,playsuit
	SET	3,c
playsuit
	LD	l,a
	LD	a,(v2bruit)
	OR	a
	JP	nz,playsui2
	SET	4,c
playsui2
	LD	d,a
	LD	a,(v3bruit)
	OR	a
	JP	nz,playsui3
	SET	5,c
playsui3
	LD	e,a
	LD	a,7
	CALL	mc
;
	LD	a,e	;	controle du generateur de bruit
	CP	l	;	bruit maximum
	JP	nc,playsui4
	LD	a,l
playsui4
	CP	d
	JP	nc,playsui5
	LD	a,d
playsui5
	LD	c,a
	LD	a,6
	CALL	mc
;
	RET	
;
playvoie
	LD	bc,(adrmus)
	LD	a,(ix+15)	; duree note
	OR	a
	JP	nz,plvsuite	; si note pas finie
	LD	a,(ix+14)	; nbr note dans sequence
	OR	a
	JP	nz,plvsuit2	; si la note n'est pas la derniere
	LD	l,(ix+10)	; adresse no de seq
	LD	h,(ix+11)
	ADD	hl,bc
	LD	e,(hl)	; adresse de seq
	INC	hl
	LD	d,(hl)
	INC	hl
	LD	a,d
	OR	e
	JP	nz,plvsuit3	; si la seq n'est pas la derniere
	LD	l,(ix+8)	; 1ere sequence
	LD	h,(ix+9)
	ADD	hl,bc
	LD	e,(hl)
	INC	hl
	LD	d,(hl)
	INC	hl
plvsuit3	OR	a
	SBC	hl,bc
	LD	(ix+10),l	; pour le prochain passage
	LD	(ix+11),h
	EX	de,hl	; nouvelle sequence
	ADD	hl,bc
	LD	a,(hl)	; nbr de notes dans seq
	INC	hl
	LD	(ix+12),l	; adrnot
	LD	(ix+13),h
;
plvsuit2	DEC	a	; nouvelle note
	LD	(ix+14),a	; nbrnot
	LD	l,(ix+12)
	LD	h,(ix+13)
	PUSH	hl
	INC	hl	; pour le prochain passage
	INC	hl
	INC	hl
	LD	(ix+12),l	; adrnot
	LD	(ix+13),h
	POP	hl
	LD	a,(hl)
	PUSH	hl
	LD	(ix+32),0	; par defaut
	CP	2
	JP	nc,plvsui18
	LD	(ix+5),0	; freq=0 si soupir ou DO 0
	LD	(ix+6),0
	LD	(ix+32),1
	OR	a
	JP	z,plvsui19
	LD	(ix+32),2
	JP	plvsui19
plvsui18	ADD	a,2
	LD	h,0
	LD	l,a
	ADD	hl,hl
	LD	de,periode
	ADD	hl,de
	LD	a,(hl)
	LD	(ix+5),a	; freq
	INC	hl
	LD	a,(hl)
	LD	(ix+6),a
plvsui19	POP	hl
	INC	hl
	LD	a,(hl)
	PUSH	af	; sauvegarder duree
	INC	hl
	LD	a,(hl)
	INC	a
	LD	(ix+2),a	; son
	DEC	a
	LD	h,0
	LD	l,a
	ADD	hl,hl
	ADD	hl,hl
	ADD	hl,hl	; *8
	LD	de,#10
	ADD	hl,de
	ADD	hl,bc
	LD	(ix+3),l	; adrson
	LD	(ix+4),h
	PUSH	hl
	POP	iy
	LD	a,(iy+6)	; flag bruit
	OR	a
	LD	a,(iy+7)	; bruit dans son
	LD	(ix+1),0	; volume=0 par defaut
	JP	z,plvsuit5
	LD	(ix+1),16	; volume  ( ---> Buzzer)
	XOR	a
plvsuit5	LD	(ix+7),a	;bruit
	LD	l,(iy+1)
	LD	h,(iy+2)
	ADD	hl,bc
	LD	(ix+16),l	; adrenv
	LD	(ix+17),h
	LD	l,(iy+4)
	LD	h,(iy+5)
	ADD	hl,bc
	LD	(ix+20),l	; adrent
	LD	(ix+21),h
	XOR	a
	LD	(ix+18),a	; durenv
	LD	(ix+22),a	; durent
	LD	a,4
	LD	(ix+26),a	; penv
	LD	(ix+27),a	; pent
	POP	af
;
plvsuite	DEC	a
	LD	(ix+15),a	; duree note
	LD	l,(ix+3)	; adrson
	LD	h,(ix+4)
	PUSH	hl
	POP	iy	; iy pointe sur les parametres du son
;
	LD	a,(ix+1)
	CP	16
	JP	z,plvent	; si buzzer sauter gestion pente
	LD	a,(ix+32)
	CP	1	; si soupir sauter gestion pente
	JP	z,plvent
plvenv	LD	a,(ix+18)	;gestion de la pente de l'ENV
	OR	a
	JP	nz,plvsuit6	; si portion pas finie
	LD	(ix+28),1	; nouvelle portion
	LD	(ix+29),0	; inverse a 1 par defaut
	LD	l,(ix+16)	; adrenv
	LD	h,(ix+17)
	LD	b,(hl)	; prends nouvelle duree
	INC	hl
	LD	c,(hl)
	INC	hl
;***************** rajout
	BIT	7,b
	JP	z,plvsui10
	LD	a,b	; si la pente n'est pas entiere
	AND	#7f
	LD	(ix+28),a	; inverse de env constant
	LD	a,c
	AND	#7f
	LD	b,a
	LD	a,1
	BIT	7,c
	JP	z,plvsui11
	NEG		; si pente negative
plvsui11	LD	c,a
;
plvsui10	LD	(ix+19),c	;pntenv
	LD	a,(ix+26)	; penv
	OR	a
	JP	nz,plvsuit7	; si env pas finie
	LD	(ix+19),0	; pente=0
	JP	plvent	; on ne change pas les parametres
;
plvsuit7	DEC	a
	LD	(ix+26),a	; penv
	LD	(ix+16),l	; adrenv
	LD	(ix+17),h
	LD	a,b
plvsuit6	DEC	a
	LD	(ix+18),a	; durenv
;
;
plvent	LD	a,(ix+32)
	CP	1
	JP	z,plvpente
	LD	a,(ix+22)	; gestion de la pente de l'ENT
	OR	a
	JP	nz,plvsuit8	; si portion pas finie
	LD	(ix+30),1	; nouvelle portion
	LD	(ix+31),0	; valeurs par defaut pour l'inverse
	LD	l,(ix+20)	; adrent
	LD	h,(ix+21)
	LD	b,(hl)	; prends nouvelle duree
	INC	hl
	LD	a,(hl)
	LD	c,a
	INC	hl
;***************** rajout
	BIT	7,b
	JP	z,plvsui12
	LD	a,b	; si la pente n'est pas entiere
	AND	#7f
	LD	(ix+30),a	; inverse de ent constant
	LD	a,c
	AND	#7f
	LD	b,a
	LD	a,1
	BIT	7,c
	JP	z,plvsui12
	NEG		; si pente negative
;
plvsui12	NEG	
	LD	(ix+23),a	; pntent
	LD	a,(ix+27)	; pent
	OR	a
	JP	nz,plvsuit9	; si ent pas finie
	LD	de,8
	OR	a
	SBC	hl,de	; retour a la 1ere portion par defaut
	LD	(ix+20),l
	LD	(ix+21),h
	LD	(ix+23),0	; et pente=0
	LD	a,(iy+3)	; flag ent
	OR	a
	JP	z,plvpente	; si non repetitive
	LD	(ix+27),3	; pent
	JP	plvent	; on reprend depuis le debut
;
plvsuit9	DEC	a
	LD	(ix+27),a	; pent
	LD	(ix+20),l	; adrent
	LD	(ix+21),h
	LD	a,b
plvsuit8	DEC	a
	LD	(ix+22),a	; durent
;
plvpente	LD	l,(ix+5)
	LD	h,(ix+6)
	LD	a,(ix+32)
	CP	1
	JP	z,plvfin	; soupir, alors sauter modifs
;
	LD	a,(ix+31)	; modification de l'ENT par la pente
	OR	a
	JP	nz,plvsui14	; si inverse pas fini
	LD	e,(ix+23)
	LD	d,0
	BIT	7,e
	JP	z,plvsui15
	DEC	d
plvsui15	ADD	hl,de
	LD	(ix+5),l
	LD	(ix+6),h
	LD	a,(ix+30)	; inverse constant
plvsui14	DEC	a
	LD	(ix+31),a
;
plvsui17	LD	a,(ix+1)
	CP	16
	JP	z,plvfin	; si buzzer
;
	LD	a,(ix+29)	; modification de l'ENV par la pente
	OR	a
	JP	nz,plvsui16
	LD	b,(ix+19)
	LD	a,(ix+1)
	ADD	a,b
	LD	(ix+1),a
	LD	a,(ix+28)
plvsui16	DEC	a
	LD	(ix+29),a
;
;
plvfin	LD	l,(ix+5)	;generation du son 
	LD	h,(ix+6)
	LD	a,(ix+24)
	LD	e,a
	LD	c,l
	CALL	mc	; freq poids faible
	LD	a,e
	INC	a
	LD	c,h
	CALL	mc	; freq poids fort
	LD	a,(ix+1)
	LD	c,a
	CP	16	; si buzzer
	JP	z,plvfin2	; alors on saute les reglages
	LD	a,15	; volume max
	SUB	(ix+0)
	LD	b,a	; b=volume a enlever
	LD	a,c	; a=volume courant
	SUB	b
	JP	nc,plvfin2	; si volume<0 alors volume=0
	XOR	a
plvfin2	LD	c,a
	LD	a,(ix+25)	; rgvolu
	CALL	mc	; volume
	RET	
;
mc	DI		;copie #BD34
	LD	B,#F4	; A - registre du PSG
	OUT	(C),A	; C - Valeur
	LD	B,#F6
	IN	A,(C)
	OR	#C0
	OUT	(C),A
	AND	#3F
	OUT	(C),A
	LD	B,#F4
	OUT	(C),C
	LD	B,#F6
	LD	C,A
	OR	#80
	OUT	(C),A
	OUT	(C),C
	EI	
	RET	
;
periode	DW	0,3822,3608,3405,3214	;table des periodes 
	DW	3034,2863,2703,2551,2408	; octave -4
	DW	2273,2145,2025
;
	DW	1911,1804,1703,1607,1517	; octave -3
	DW	1432,1351,1276,1204,1136
	DW	1073,1012
;
	DW	956,902,851,804,758,716		; octave -2
	DW	676,638,602,568,536,506
;
	DW	478,451,426,402,379,358		; octave -1
	DW	338,319,301,284,268,253
;
	DW	239,225,213,201,190,179		; octave 0
	DW	169,159,150,142,134,127
;
	DW	119,113,106,100,95,89		; octave 1
	DW	84,80,75,71,67,63
;
	DW	60,56,53,50,47,45,42,40		; octave 2
	DW	38,36,34,32
;
	DW	30,28,27,25,24,22,21		; octave 3
	DW	20,19,18,17,16
;
	DW	15,14,13,12,12,11,10		; octave 4 (fictif)
;
;
.musicdata
; doublon NDC	incbin "Duffy_Binaries\Benjy_Player\CEDRIC31.BIN"
; doublon NDC	incbin "Duffy_Binaries\Benjy_Player\CEDRIC32.BIN"
; doublon NDC	incbin "Duffy_Binaries\Benjy_Player\CEDRIC35.BIN"
;	incbin "Duffy_Binaries\Benjy_Player\CEDRIC36.BIN"
; doublon NDC	incbin "Duffy_Binaries\Benjy_Player\CEDRIC37.BIN"
; doublon NDC	incbin "Duffy_Binaries\Benjy_Player\CEDRIC38.BIN"
;	incbin "Duffy_Binaries\Benjy_Player\CEDRIC39.BIN"
;	incbin "Duffy_Binaries\Benjy_Player\CEDRIC40.BIN"
; doublon NDC	incbin "Duffy_Binaries\Benjy_Player\CEDRIC41.BIN"
;	incbin "Duffy_Binaries\Benjy_Player\CEDRIC42.BIN"
; doublon NDC	incbin "Duffy_Binaries\Benjy_Player\CEDRIC43.BIN"
;	incbin "Duffy_Binaries\Benjy_Player\CEDRIC44.BIN"
;	incbin "Duffy_Binaries\Benjy_Player\CEDRIC45.BIN"
;	incbin "Duffy_Binaries\Benjy_Player\CEDRIC46.BIN"
;	incbin "Duffy_Binaries\Benjy_Player\CEDRIC47.BIN"
;	incbin "Duffy_Binaries\Benjy_Player\CEDRIC49.BIN"
;	incbin "Duffy_Binaries\Benjy_Player\CEDRIC50.BIN"
;	incbin "Duffy_Binaries\Benjy_Player\CEDRIC54.BIN" warning need NDC player !!!
;	incbin "Duffy_Binaries\Benjy_Player\CEDRIC55.BIN"
;	incbin "Duffy_Binaries\Benjy_Player\CEDRIC62.BIN"
;	incbin "Duffy_Binaries\Benjy_Player\CEDRIC64.BIN"
;	incbin "Duffy_Binaries\Benjy_Player\CEDRIC65.BIN"

.game_name
	db "Duffy Music CEDRIC51",0

.game_year
	db "199x",0
.game_publisher
	db "Duffy & Benjy & NDC Team",0
.music_author
	db "Duffy",0
.music_comment
	db "Player pour MUSIC PRO par Benjy",0

	read "music_end_v1_0.asm"
